home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / raytrace / rayshade / graphtal.lzh / Graphtal.Amiga / ViewTransform.C < prev    next >
C/C++ Source or Header  |  1992-11-17  |  3KB  |  124 lines

  1. /*
  2.  * ViewTransform.C - general view transformation.
  3.  *
  4.  * Copyright (C) 1992, Christoph Streit (streit@iam.unibe.ch)
  5.  *                     University of Berne, Switzerland
  6.  * All rights reserved.
  7.  *
  8.  * This software may be freely copied, modified, and redistributed
  9.  * provided that this copyright notice is preserved on all copies.
  10.  *
  11.  * You may not distribute this software, in whole or in part, as part of
  12.  * any commercial product without the express consent of the authors.
  13.  *
  14.  * There is no warranty or other guarantee of fitness of this software
  15.  * for any purpose.  It is provided solely "as is".
  16.  *
  17.  */
  18.  
  19. #include "ViewTransform.h"
  20. #include "Error.h"
  21.  
  22. //___________________________________________________________ ViewTransform
  23.  
  24.  
  25. ViewTransform::ViewTransform(const Vector& Eye, const Vector& Lookat,
  26.                  const Vector& Up, real Fov, int ResX, int ResY)
  27. : eye(Eye), lookat(Lookat), up(Up), fov(Fov), resX(ResX), resY(ResY)
  28. {
  29.   buildView();
  30. }
  31.  
  32. ViewTransform::ViewTransform(const BoundingBox& b, const Vector& Up, real Fov, 
  33.                  int ResX, int ResY)
  34. : up(Up), fov(Fov), resX(ResX), resY(ResY)
  35. {
  36.   real widthX2 = 0.5*(b.xmax()-b.xmin());
  37.   real widthY2 = 0.5*(b.ymax()-b.ymin());
  38.   real height2 = 0.5*(b.zmax()-b.zmin());
  39.  
  40.   if (widthX2 > widthY2) {
  41.     // let's look to the xz-plane
  42.     if (widthX2 >= height2)
  43.       eye[1] = b.ymax() + widthX2/tan(dtor(fov/2));
  44.     else
  45.       eye[1] = b.ymax() + height2/tan(dtor(fov/2));
  46.     eye[0] = lookat[0] = b.xmin() + widthX2;
  47.     lookat[1] = b.ymax();
  48.   } 
  49.   else {
  50.     // let's look to the yz-plane
  51.     if (widthY2 >= height2)
  52.       eye[0] = b.xmax() + widthY2/tan(dtor(fov/2));
  53.     else
  54.       eye[0] = b.xmax() + height2/tan(dtor(fov/2));
  55.     eye[1] = lookat[1] = b.ymin() + widthY2;
  56.     lookat[0] = b.xmax();
  57.   }
  58.   eye[2] = lookat[2] = b.zmin()+height2; 
  59.   
  60.   buildView();
  61. }
  62.  
  63. Vector ViewTransform::transformWorld2Screen(const Vector& p)
  64. {
  65.   Vector vp = p*viewmat;
  66.  
  67.   if (equal(vp[2], 0)) 
  68.     return Vector(0,0,0);
  69.  
  70.   real scale = widthOfViewplane/vp[2];
  71.   vp[0] = resX*(0.5+vp[0]*scale);
  72.   vp[1] = resY*(0.5+vp[1]*scale);
  73.  
  74.   return vp;
  75. }
  76.  
  77. Vector ViewTransform::transformWorld2View(const Vector& p)
  78. {
  79.   return p*viewmat;
  80. }
  81.  
  82. Vector ViewTransform::transformView2Screen(const Vector& p)
  83. {
  84.   if (equal(p[2], 0)) 
  85.     return Vector(0,0,0);
  86.  
  87.   Vector vp = p;
  88.   real scale = widthOfViewplane/vp[2];
  89.   vp[0] = resX*(0.5+vp[0]*scale);
  90.   vp[1] = resY*(0.5+vp[1]*scale);
  91.  
  92.   return vp;
  93. }
  94.  
  95. // buildView assumes that eye, lookat, up, fov, resX, resY are already set!!!
  96. void ViewTransform::buildView()
  97. {
  98.   Vector n,v,u;
  99.  
  100.   n = lookat - eye; n.normalize();
  101.   v = up - (n^up)*n;
  102.   if (v.normalize() == 0) 
  103.     Error(ERR_PANIC, "The view and up directions are identical?");
  104.   u = n * v; 
  105.   widthOfViewplane = 0.5/(tan(dtor(fov)/2));
  106.  
  107.   viewmat(0,0) = u[0]; viewmat(1,0) = u[1]; viewmat(2,0) = u[2];
  108.   viewmat(0,1) = v[0]; viewmat(1,1) = v[1]; viewmat(2,1) = v[2];
  109.   viewmat(0,2) = n[0]; viewmat(1,2) = n[1]; viewmat(2,2) = n[2];
  110.   viewmat(3,0) = -eye[0]*u[0] - eye[1]*u[1] - eye[2]*u[2];
  111.   viewmat(3,1) = -eye[0]*v[0] - eye[1]*v[1] - eye[2]*v[2];
  112.   viewmat(3,2) = -eye[0]*n[0] - eye[1]*n[1] - eye[2]*n[2];
  113. }
  114.  
  115. ostream& operator<<(ostream& os, const ViewTransform& view)
  116. {
  117.   os << "Eye:    " << view.eye    << '\n'
  118.      << "Lookat: " << view.lookat << '\n'
  119.      << "Up:     " << view.up     << '\n'
  120.      << "Fov:    " << view.fov    << '\n';
  121.  
  122.   return os;
  123. }
  124.